#include "common_module.h"

#include <boost/asio.hpp>
using namespace boost;
using namespace boost::asio;

#include <common/log/log.h>
#include <common/net/message_parse.h>
#include <common/net/session.h>

#include <protocols/protos/common.pb.h>
using namespace proto::common;
#include <protocols/protos/db.pb.h>
using namespace proto::db;
#include <protocols/protos/tables.pb.h>
using namespace proto::tables;

#include <common/base/module_mgr.h>
#include <common/base/server_mgr.h>
#include <common/utils/util.h>

#include "base/player.h"
#include "base/player_mgr.h"
#include "base/sub_server_mgr.h"

bool CommonModule::doDispatch(const std::shared_ptr<SubServerMgr>& submgr,
                             const std::shared_ptr<Player>& player,
                             const MessageID& msgID,
                             const char* buf,
                             std::size_t bufSize)
{
    LOG_WARN("doDispatch not implement.");
    return false;
}

bool CommonModule::doDispatch(const std::shared_ptr<Session>& session,
                              const MessageID& msgID,
                              const char* buf,
                              std::size_t bufSize)
{
    switch (msgID.stMsg.msgID)
    {
    case C2S_COMMON_GATE_REQ:
        return onCommonGateReq(session, msgID, buf, bufSize);

    default:
        return false;
    }

    return false;
}

bool CommonModule::onCommonGateReq(const std::shared_ptr<Session>& session,
                                   const MessageID& msgID,
                                   const char* buf,
                                   std::size_t bufSize)
{ // recv req msg from game_server
    CommonGateReq req;
    if (!req.ParseFromArray(buf, bufSize))
    {
        LOG_ERROR("Parse proto data failed.");
        return false;
    }
    const auto& subMgr = ServerMgr::get().getSubServ<SubServerMgr>();
    const auto& playerMgr = subMgr->getSubMgr<PlayerMgr>(SubManagerType::ePlayer);
    if (!playerMgr)
    {
        LOG_ERROR("Player manager not found.");
        return false;
    }

    auto player = playerMgr->getPlayer(req.player_id());
    if (!player)
    {
        player = std::make_shared<Player>(req.player_id());
        if (!player->init())
        {
            LOG_ERROR("player was not found. id: " << req.player_id());
            return false;
        }
        playerMgr->addPlayer(player);
    }
    player->setGsSession(session);
    MessageID id(req.msg_id());
    auto moduleMgr = ServerMgr::get().getMgr<ModuleMgr>(ManagerType::eModule);
    if (!moduleMgr)
    {
        LOG_ERROR("No found module manager.");
        return false;
    }
    auto module = moduleMgr->getModule(id.stMsg.moduleType);
    if (!module)
    {
        LOG_ERROR("No found module " << std::hex << id.msgID) ;
        return false;
    }
    LOG_INFO("dispatch player id: " << player->getID() << " msg: " << std::hex << id.msgID);
    return module->doDispatch(subMgr, player, id, req.msg().c_str(), req.msg_len());
}
